// file:os/memcache.h
// time:2021.2.1
// autor:jiangxinpeng
// copyright:(C) 2020-2050 by jiangxinpneg,All right are reserved.

#ifndef ARCH_MEMCACHE_H
#define ARCH_MEMCACHE_H

#include <lib/type.h>
#include <lib/stddef.h>
#include <lib/list.h>
#include <lib/bitmap.h>
#include <os/mutexlock.h>

#define MEM_CACHE_NAME_LEN 24

// low page size cache object alloc in same pages
// reserved size for bitsmap
#define MEM_CACHE_PAGERESERVED_SIZE 128

#define MEM_CACHE_SIZE_MAX 2 * MB

#define MEM_OBJECT_SIZE_MAX (24 * MB)

// mem cache group
typedef struct mem_group
{
    list_t list;          // point cache list
    bitmap_t map;         // alloc status bitmap
    uint8_t *object;      // object cluster point
    uint32_t using_count; // object are using
    uint32_t free_count;  // free object count
    flags_t flags;        // group flags
} mem_group_t;

// mem cache struct
typedef struct mem_cache
{
    list_t full_groups;    // object full used
    list_t partial_groups; // object only used partial
    list_t free_groups;    // object are not used

    uint32_t object_size;  // object size;
    flags_t flags;         // canche flags
    uint32_t object_count; // object count

    char name[MEM_CACHE_NAME_LEN]; // canche name

    mutexlock_t mutex; // mutex lock
} mem_cache_t;

// mem cache size
typedef struct mem_cache_size
{
    uint32_t cache_size;    // canche size
    mem_cache_t *mem_cache; // mem canche point
} mem_cache_size_t;

// large mem object
typedef struct
{
    uint32_t vbase;
    uint32_t size;
    list_t list;
} large_mem_object_t;

int MemCacheInit(mem_cache_t *cache, char *name, size_t size, flags_t flag);
int MemGroupInit(mem_cache_t *cache, mem_group_t *group, flags_t flags);
int MemGroupCreate(mem_cache_t *cache, flags_t flags);
// alloc page to mem cache
void MemCacheFreePage(uint32_t page, uint32_t size);
void *MemCacheAllocPage(uint32_t count);
// alloc object in cache group
void *MemCacheAlloc(mem_cache_t *cache, mem_group_t *group);
void *MemCacheAllocObject(mem_cache_t *cache);
void MemCachesInit();
// kernel mem malloc
void *KMemAlloc(size_t size);
void KMemFree(void *object);

#define MemAlloc KMemAlloc
#define MemFree KMemFree
#endif